"""
数据库模块 - MySQL 异步连接服务

此模块负责根据应用配置，创建并提供可注入的、针对 MySQL 的
SQLAlchemy 异步引擎 (`AsyncEngine`) 和会话工厂 (`async_sessionmaker`)。
"""
from typing import AsyncGenerator
from sqlalchemy.ext.asyncio import (
    AsyncEngine,
    AsyncSession,
    async_sessionmaker,
    create_async_engine,
)

from axiom_boot.conf.manager import Settings
from axiom_boot.di import autowired, service, conditional_on_setting
from axiom_boot.core.exceptions import FrameworkException


@conditional_on_setting(key="database_enabled")
@conditional_on_setting(key="mysql_url", match_if_present=True)
@service(
    name="mysql_engine",
    provides=AsyncEngine,
)
async def provide_mysql_engine(settings: Settings) -> AsyncGenerator[AsyncEngine, None]:
    """
    提供一个生命周期安全的 SQLAlchemy 异步引擎实例 (MySQL)。

    这是一个条件化的工厂服务，只有在配置了 `mysql_url` 时才会被注册。
    它使用异步生成器模式，确保在应用关闭时能安全地释放引擎资源。
    """
    if not settings.mysql_url:
        raise FrameworkException(
            "数据库功能已启用 (DATABASE_ENABLED=true), 但 mysql_url 未配置。"
        )
    try:
        engine = create_async_engine(
            settings.mysql_url,
            pool_size=settings.mysql_pool_size,
            max_overflow=settings.mysql_max_overflow,
            pool_pre_ping=settings.mysql_pool_pre_ping,
            echo=settings.mysql_echo,
        )
        yield engine
    except Exception as e:
        raise FrameworkException(f"创建 MySQL 引擎失败: {e}")
    finally:
        if 'engine' in locals() and isinstance(engine, AsyncEngine):
            await engine.dispose()


@conditional_on_setting(key="database_enabled")
@conditional_on_setting(key="mysql_url", match_if_present=True)
@service(
    name="async_sessionmaker",
    provides=async_sessionmaker,
)
def provide_mysql_session_factory(
    engine: AsyncEngine = autowired("mysql_engine")
) -> async_sessionmaker[AsyncSession]:
    """
    提供一个 SQLAlchemy 异步会话工厂 (MySQL)。
    它依赖于 `mysql_engine` 服务。
    """
    return async_sessionmaker(engine, class_=AsyncSession, expire_on_commit=False) 